﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using System.IO;
using System.ComponentModel;

namespace BDSim
{
    /// <summary>
    /// 星座模型
    /// </summary>
    [TypeConverter(typeof(ExpandableObjectConverter))]   
    public class Constellation : SpaceBase
    {
        #region 字段

        private SpaceSegment _Parent;
        private ConstellationFeatures _ConstellationFeature=new ConstellationFeatures();
        ObservableCollection<Satellite> _SatelliteCollection = new ObservableCollection<Satellite>();
        private ConstellationDataProvider _ConstellationDataProvider=new ConstellationDataProvider();


        string path;

        #endregion

        #region 属性

        /// <summary>
        /// 星座的上一级，空间段
        /// </summary>
        [XmlIgnore, Browsable(false)]
        public SpaceSegment Parent
        {
            get { return _Parent; }
            set { _Parent = value; }
        }

        [Category("基本信息"), Description(""), PropertyOrder(1)]
        public virtual string Name
        {
            get { return _Name; }
            set
            {
                if (Parent != null)
                {

                    foreach (var item in Parent.ConstellationList)
                    {
                        if (item.Name == value)
                        {
                            DlgReportPropertyInfo("名字无效，已存在名为“" + value + "”的星座!");
                            return;
                        }
                    }
                }
                _Name = value;
                NotifyPropertyChanged("Name");
            }
        }

        /// <summary>
        /// 星座中卫星总数
        /// </summary>
        [CategoryAttribute("卫星数"), DescriptionAttribute("星座中的总卫星数")]
        public int SatNum
        {
            get { return SatelliteCollection.Count; }
        }

        /// <summary>
        /// 星座特性
        /// </summary>
        [CategoryAttribute("星座特性"), DescriptionAttribute("星座特性参数"), DisplayName("星座特性参数"), TypeConverter(typeof(PropertySorter))]
        public ConstellationFeatures ConstellationFeature
        {
            get { return _ConstellationFeature; }
            set { _ConstellationFeature = value; }
        }  
            
        /// <summary>
        /// 卫星集合
        /// </summary>
        //[XmlIgnore]
        [Browsable(false)]
        public ObservableCollection<Satellite> SatelliteCollection
        {
            get { return _SatelliteCollection; }
            set { _SatelliteCollection = value; NotifyPropertyChanged("SatelliteCollection"); }
        }

        /// <summary>
        /// 数据提供
        /// </summary>
        [XmlIgnore, Browsable(false)]
        public ConstellationDataProvider ConstellationDataProvider
        {
            get { return _ConstellationDataProvider; }
            set { _ConstellationDataProvider = value; }
        }

       

        #endregion

        #region 方法

        public Constellation()
        {
            _ConstellationFeature.Parent = this;
            _ConstellationDataProvider.Parent = this;
            _ConstellationDataProvider.DefineCommand();
            Menu.ItemsSource = _ConstellationDataProvider.MenuCommandList;
        }

        
        #region 初始化
        public override void Init()
        {
            path = Directory.GetCurrentDirectory() + "\\DataRecords\\空间段\\自定义数据_" ;
            DateTime NowTime = DateTime.Now;
            string NowTimeString = NowTime.Year.ToString() + string.Format("{0:D2}", NowTime.Month) + string.Format("{0:D2}", NowTime.Day) +
                "_" + string.Format("{0:D2}", NowTime.Hour) + "_" + string.Format("{0:D2}", NowTime.Minute) + "_" + string.Format("{0:D2}", NowTime.Second);
            path = path + NowTimeString+"\\";
            base.Init();
            foreach (var item in SatelliteCollection)
            {
                item.Init();

              //  if (Scenario._IsTestingMode)
               // {
                    SaveSatTextData(path, item);
               // }
            }
        }
        #endregion

        #region 单步运行
        public override void StepRun()
        {
            base.StepRun();
            foreach (var item in SatelliteCollection)
            {
                item.StepRun();
            }
        }
        #endregion


        #endregion

        /// <summary>
        /// 写轨道和钟差数据文件
        /// </summary>
        void SaveSatTextData(string TextDirectory,Satellite sat)
        {

            TextDirectory = TextDirectory  + this.Name;

            string OrbitECIFileName = TextDirectory + "\\轨道数据\\ECI\\";
            string OrbitECFFileName = TextDirectory + "\\轨道数据\\ECF\\";
            string ClkFileName = TextDirectory + "\\钟差数据\\";

            if (!Directory.Exists(OrbitECIFileName))
            {
                Directory.CreateDirectory(OrbitECIFileName);
            }

            if (!Directory.Exists(OrbitECFFileName))
            {
                Directory.CreateDirectory(OrbitECFFileName);
            }

            if (!Directory.Exists(ClkFileName))
            {
                Directory.CreateDirectory(ClkFileName);
            }

            //OrbitECIFileName += sat.Name + ".txt";//zly
            //OrbitECFFileName += sat.Name + ".txt";//zly
            OrbitECIFileName += "BDSim_" + sat.Name + "_ECI.txt";
            OrbitECFFileName += "BDSim_" + sat.Name + "_ECF.txt";

            ClkFileName += "BDSim_" + sat.Name + ".txt";

            OrbitDataWriter orbitWriterECI = new OrbitDataWriter();
            OrbitDataWriter orbitWriterECF = new OrbitDataWriter();

            ClockDataWriter clkWriter = new ClockDataWriter();

            List<OrbitSimData> InterpolationOrbitData =sat.GenerateStepOrbit((int)GlobalStepSize);
            List<ClkSimData> InterpolationClockData = sat.GenerateStepCLKErr((int)GlobalStepSize);

            //  写插值后的ECI、ECF数据
            foreach (var SatOrbitItem in InterpolationOrbitData)
            {
                NodePosVel temp_ECF = new NodePosVel();
                //TimeSpaceDll.ECI2ECF(SatOrbitItem.SatPV_ECI, 0, 0, out temp_ECF);//zly
                TimeSpaceDll.ECI2ECF(SatOrbitItem.SatPV_ECI, 0, 0, out temp_ECF);//zly

                OrbitSimData satpv_ECI = SatOrbitItem;
                //存储数据时将UTC时间转换为GPS时，zly
                if (Scenario._IsTestingMode)
                {
                    UTCTime GPST = new UTCTime();
                    double GPS_JD;
                    TimeSpaceDll.UTC2GPST(SatOrbitItem.SatPV_ECI.epoch.Jd, out GPS_JD);
                    GPST.Jd = GPS_JD;
                    TimeSpaceDll.CAL2UTC(out GPST, 2);
                   
                    satpv_ECI.SatPV_ECI.epoch = GPST;
                    //存储数据时将UTC时间转换为GPS时，zly
                }
                //orbitWriterECI.WriteFile(SatOrbitItem.SatPV_ECI);//zly
                
                //zly
                UTCToStringClass utcstr = new UTCToStringClass();
                string UTCStr = utcstr.NewUTCToString(satpv_ECI.SatPV_ECI.epoch);
                string content = UTCStr + "    " + satpv_ECI.SatPV_ECI.X.ToString("0.000000").PadLeft(17, ' ') +
                    "    " + satpv_ECI.SatPV_ECI.Y.ToString("0.000000").PadLeft(17, ' ') +
                    "    " + satpv_ECI.SatPV_ECI.Z.ToString("0.000000").PadLeft(17, ' ') +
                    "    " + satpv_ECI.SatPV_ECI.vx.ToString("0.000000").PadLeft(14, ' ') +
                    "    " + satpv_ECI.SatPV_ECI.vy.ToString("0.000000").PadLeft(14, ' ') +
                    "    " + satpv_ECI.SatPV_ECI.vz.ToString("0.000000").PadLeft(14, ' ') + "\r\n";

                File.AppendAllText(OrbitECIFileName, content);
                //zly

                
                //zly
                string tempcontent = UTCStr + "    " +
                              temp_ECF.X.ToString("0.000000").PadLeft(17, ' ') +
                     "    " + temp_ECF.Y.ToString("0.000000").PadLeft(17, ' ') +
                     "    " + temp_ECF.Z.ToString("0.000000").PadLeft(17, ' ') +
                     "    " + temp_ECF.vx.ToString("0.000000").PadLeft(14, ' ') +
                     "    " + temp_ECF.vy.ToString("0.000000").PadLeft(14, ' ') +
                     "    " + temp_ECF.vz.ToString("0.000000").PadLeft(14, ' ') + "\r\n";

                File.AppendAllText(OrbitECFFileName, tempcontent);
                //zly
            }

            //  写插值后的钟差数据
            foreach (var ClkItem in InterpolationClockData)
            {
                //存储数据时将UTC时间转换为GPS时，zly
                UTCTime SaveTime = new UTCTime();
                SaveTime = ClkItem.SimTime;
                if (Scenario._IsTestingMode)
                {
                    double GPS_JD;
                    TimeSpaceDll.UTC2GPST(ClkItem.SimTime.Jd, out GPS_JD);
                    SaveTime.Jd = GPS_JD;
                    TimeSpaceDll.CAL2UTC(out SaveTime, 2);
                    //存储数据时将UTC时间转换为GPS时，zly
                }
                //clkWriter.WriteFile(ClkItem.SimTime, ClkItem.ClkError);//zly
                
                //zly
                UTCToStringClass utcstr = new UTCToStringClass();
                string content = utcstr.NewUTCToString(SaveTime) + "    " + ClkItem.ClkError.ToString().PadLeft(20, ' ') + "\r\n";
                File.AppendAllText(ClkFileName, content);
                //zly
            }
        }

    }  

}
